#include <jni.h>
#include <string>
#include <android/bitmap.h>

extern "C" {
#include "gif_lib.h"
}
//8  1   16  2  24  3
struct GifBean {
    int current_frame;
    int total_frame;
    int *delays;
};


#define  argb(a, r, g, b) ( ((a) & 0xff) << 24 ) | ( ((b) & 0xff) << 16 ) | ( ((g) & 0xff) << 8 ) | ((r) & 0xff)

void drawFrame(GifFileType *gifFileType, AndroidBitmapInfo info, void *pixels) {
    GifBean *gifBean = static_cast<GifBean *>(gifFileType->UserData);
    SavedImage savedImage = gifFileType->SavedImages[gifBean->current_frame];
    GifImageDesc frameInfo = savedImage.ImageDesc;
    ColorMapObject *colorMapObject = frameInfo.ColorMap;
    int *px = (int *) pixels;
    int *line;
    int pointPixel;
    GifByteType gifByteType;
    GifColorType gifColorType;
    for (int y = frameInfo.Top; y < frameInfo.Top + frameInfo.Width; ++y) {
        line = px;
        for (int x = frameInfo.Left; x < frameInfo.Left + frameInfo.Height; ++x) {
            pointPixel = (y - frameInfo.Top) * frameInfo.Width + (x - frameInfo.Left);
            gifByteType = savedImage.RasterBits[pointPixel];
            gifColorType = colorMapObject->Colors[gifByteType];
            line[x] = argb(255, gifColorType.Red, gifColorType.Green, gifColorType.Blue);
        }
        //遍历条件     转到下一行
        px = (int *) ((char *) px + info.stride);
    }
}

extern "C"
JNIEXPORT  jint JNICALL
Java_com_example_gifnativedemo_GifHandler_loadGif(JNIEnv *env, jclass clazz, jstring path_) {
    const char *path = env->GetStringUTFChars(path_, 0);
    int erro;//打开失败还是成功
    GifFileType *fileType = DGifOpenFileName(path, &erro);
    DGifSlurp(fileType);//进行gif的初始化，拿到gif的详细信息, GifFlieType是一个保存gif天动画的结构体，里面保存着gif的宽高和总帧数等信息
    GifBean *gifBean = static_cast<GifBean *>(malloc(sizeof(GifBean)));//开辟一个gifbean对象的内存空间
    memset(gifBean, 0, sizeof(GifBean));//将对象附一个默认值
    fileType->UserData = gifBean;
    gifBean->current_frame = 0;
    gifBean->total_frame = fileType->ImageCount;//总帧数
    env->ReleaseStringUTFChars(path_, path);//释放内存
    return 0;
}
extern "C"
JNIEXPORT jint JNICALL
Java_com_example_gifnativedemo_GifHandler_getWidth(JNIEnv *env, jclass clazz, jlong gif_hander) {
    // TODO: implement getWidth()
    GifFileType *gifFileType = reinterpret_cast<GifFileType *>(gif_hander);
    return gifFileType->SWidth;
}

extern "C"
JNIEXPORT jint JNICALL
Java_com_example_gifnativedemo_GifHandler_getHeight(JNIEnv *env, jclass clazz, jlong gif_hander) {
    // TODO: implement getHeight()
    GifFileType *gifFileType = reinterpret_cast<GifFileType *>(gif_hander);
    return gifFileType->SHeight;
}
extern "C"
JNIEXPORT jint JNICALL
Java_com_example_gifnativedemo_GifHandler_updateFrame(JNIEnv *env, jclass clazz, jlong gif_point,
                                                      jobject bitmap) {
    GifFileType *gifFileType = reinterpret_cast<GifFileType *>(gif_point);
    int width = gifFileType->SWidth;
    int height = gifFileType->SHeight;
    AndroidBitmapInfo bitmapInfo;
    AndroidBitmap_getInfo(env, bitmap, &bitmapInfo);
    width = bitmapInfo.width;
    height = bitmapInfo.height;
    void *pixels;
    AndroidBitmap_lockPixels(env, bitmap, &pixels);
    drawFrame(gifFileType, bitmapInfo, pixels);
    AndroidBitmap_unlockPixels(env, bitmap);
    GifBean *gifBean = static_cast<GifBean *>(gifFileType->UserData);
    gifBean->current_frame++;
    if (gifBean->current_frame >= gifBean->total_frame - 1) {
        gifBean->current_frame = 0;
    }
    return 100;
}
